home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / archiver / lsize25.zip / LSIZE.C < prev    next >
C/C++ Source or Header  |  1994-01-18  |  26KB  |  717 lines

  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <dir.h>
  6. #define BUF_SIZ 2048
  7. #define BSIZE 32760
  8. #define MAX_SUB_FILES 4000
  9. #define demand(fact, remark) {\
  10.     if (!(fact)) {\
  11.         fprintf(stderr, "\nError ->  " #fact "\n");\
  12.         fprintf(stderr, #remark "\n");\
  13.         perror("error");\
  14.         fcloseall();\
  15.         _setcursortype(_NORMALCURSOR);\
  16.         abort();\
  17.         exit(1);\
  18.     }\
  19. }
  20. /************************** Variables *************************************/
  21. char buffer[BUF_SIZ];           /* buffer for reading and writing files */
  22. char outbuf[BSIZE];             /* disk output buffer */
  23. typedef struct{                 /* Structure to hold file info */
  24.     unsigned long int position;  /* location of file in LZH from beginning */
  25.     char filenum;                /* subfile number file will be written to */
  26.     unsigned long int size;      /* file size */
  27.     char *name;                  /* file name - allocated dynamically */
  28.     unsigned long int size2;
  29.     unsigned long int position2;
  30.     } record;
  31. record *file[MAX_SUB_FILES];    /* array of pointers to file records */
  32. unsigned long int fsize;        /* used to hold various file sizes    */
  33. unsigned long int nsize[256];   /* subfile lengths */
  34. unsigned long int i;            /* iteration variable */
  35. unsigned long int skip;         /* used to hold skip file length     */
  36. unsigned long int ovrwrt;       /* overwrite flag(0=dont ovrwrt)     */
  37. unsigned long int tsize;        /* target file size(max for subfiles */
  38. unsigned long int bcount;       /* byte count: used for file buffer  */
  39. unsigned int position;
  40. unsigned int skipper;
  41. unsigned int fsize2;
  42. unsigned int rotaten;
  43. char flag;
  44. unsigned long int startdir=0;
  45. unsigned long int dirsize=0;
  46. char *strptr;
  47. unsigned char subfile;          /* subfile number */
  48. unsigned char max;              /* max = total number of subfiles    */
  49. int count;                      /* count = number of files in archive    */
  50. int count2;
  51. int str_len;
  52. unsigned long int total_size;   /* accumulator -total size of a subfile */
  53. unsigned int hsize;             /* header size */
  54. int j,k;                        /* loop counters */
  55. char temp[MAXPATH];             /* temp string storage */
  56. char prefix[MAXPATH];           /* prefix for target files */
  57. char suffix[4];                 /* holds subfile number suffix 1,2,3,...*/
  58. char ifile[MAXPATH];            /* name of source file */
  59. char tfile[MAXPATH];            /* temp storage for manip file names*/
  60. char ans;                       /* answer for: Overwrite file?          */
  61. char drive[MAXDRIVE];
  62. char dir[MAXDIR];
  63. char comment[85];
  64. char iname[MAXFILE];
  65. char oname[MAXFILE+8];
  66. char ext[MAXEXT];
  67. char saveext[MAXEXT];
  68. int flags;
  69. char trunc_flag=0;
  70. FILE *fp,*sfp;
  71. void sortfs(void);
  72. void help(void);
  73. /********* MAIN PROGRAM **********/
  74. void main(int argc, char *argv[]) /** argc = number of command line args ***/
  75. {                              /**** argv = array containing actual args **/
  76. int lastarg=argc-1;
  77. if(argc<3) help();
  78. if(strtol(argv[lastarg],NULL,10)<0)
  79.     { puts("Error: Invalid file size"); exit(1);}
  80. if(!strcmp(argv[lastarg],"1.44M") || !strcmp(argv[lastarg],"1.44m")\
  81. || !strcmp(argv[lastarg],"1.4M")|| !strcmp(argv[lastarg],"1.4m")) tsize=1457664;
  82. else if(!strcmp(argv[lastarg],"720K") || !strcmp(argv[lastarg],"720k")) tsize=730112;
  83. else if(!strcmp(argv[lastarg],"1.2M") || !strcmp(argv[lastarg],"1.2m")) tsize=1457664;
  84. else if(!strcmp(argv[lastarg],"360K") || !strcmp(argv[lastarg],"360k")) tsize=362496;
  85. else tsize=strtoul(argv[lastarg],NULL,10);
  86. if(tsize<=0) help();
  87.  
  88. strcpy(ifile,argv[1]);
  89. flags=fnsplit(ifile,drive,dir,iname,ext);
  90. if(!(flags & EXTENSION)){        /* If no extension on source file */
  91.     strcpy(tfile,ifile);
  92.     strcat(tfile, ".LZH");                       // try LZH
  93.     fp=fopen(tfile, "rb");
  94.     if(!fp){
  95.         strcpy(tfile,ifile);
  96.         strcat(tfile, ".ARJ");                    // try ARJ
  97.         fp=fopen(tfile, "rb");
  98.         }
  99.     if(!fp){
  100.         strcpy(tfile,ifile);                      // try ZIP
  101.         strcat(tfile, ".ZIP");
  102.         fp=fopen(tfile, "rb");
  103.         }
  104.     strcpy(ifile, tfile);
  105.     fclose(fp);
  106.     }
  107. fp=fopen(ifile, "rb");                                // Open source file
  108. demand(fp!=NULL, Could not open source file);
  109. strupr(ifile);                                  // conv to upper case
  110. flags=fnsplit(ifile,drive,dir,iname,ext);
  111. strcpy(saveext, ext);                          // save file name extension
  112. /********************************* Search LZH file ************************/
  113. /*
  114.     1 byte  - header size
  115.     1 byte  - header checksum
  116.     5 bytes - file header/signature
  117.     4 bytes - compressed size
  118.     4 bytes - original size
  119.     4 bytes - date/time
  120.     2 bytes - file attributes
  121.     n bytes - file path\name (ends with x00)
  122.     n bytes - file data
  123.     .
  124.     .
  125.     .
  126. */
  127. printf("\n...searching file %s\n",ifile);
  128. skip=0;
  129. count=0;
  130. if(!strcmp(ext,".LZH")) {
  131. while(!feof(fp)){
  132.     demand(count<MAX_SUB_FILES, Sorry - Too many files in LZH);
  133.     file[count]=malloc(sizeof(record));
  134.     demand(file[count]!=NULL, Out of memory);
  135.     file[count]->position=skip;
  136.     hsize=fgetc(fp);
  137.     demand(!ferror(fp),Read error);
  138.     if(hsize==0) break;
  139.     if(feof(fp)) break;
  140.     fgetc(fp);
  141.     if(feof(fp)) break;
  142.     fgets(temp,6,fp);
  143.     demand(!strncmp(temp,"-lh",3),LZH file has problems);
  144.     fread(&fsize,sizeof(long),1,fp);
  145.     file[count]->size=fsize+hsize+2;
  146.     file[count]->filenum=0;
  147.     skip+=file[count]->size;
  148.     fseek(fp, (long)10, SEEK_CUR);
  149.     fgets(temp,fgetc(fp)+1,fp);
  150.     file[count]->name = malloc(strlen(temp)+1);
  151.     demand(file[count]->name!=NULL, Out of memory!);
  152.     strcpy(file[count]->name, temp);
  153.     count++;
  154.     fseek(fp, fsize+5, SEEK_CUR);
  155.  }
  156. }
  157. /*********************** SEARCH ARJ FILE **********************************
  158.       ARJ archives contains two types of header blocks:
  159.  
  160.     Archive main header - This is located at the head of the archive
  161.     Local file header   - This is located before each archived file
  162.  
  163.       Structure of main header (low order byte first):
  164.  
  165.       Bytes Description
  166.       ----- -------------------------------------------------------------------
  167.          2   header id (main and local file) = 0x60 0xEA
  168.          2   basic header size (from 'first_hdr_size' thru 'comment' below)
  169.          = first_hdr_size + strlen(filename) + 1 + strlen(comment) + 1
  170.          = 0 if end of archive
  171.          maximum header size is 2600
  172.  
  173.          1   first_hdr_size (size up to and including 'extra data')
  174.          1   archiver version number
  175.          1   minimum archiver version to extract
  176.          1   host OS   (0 = MSDOS, 1 = PRIMOS, 2 = UNIX, 3 = AMIGA, 4 = MAC-OS)
  177.               (5 = OS/2, 6 = APPLE GS, 7 = ATARI ST, 8 = NEXT)
  178.               (9 = VAX VMS)
  179.          1   arj flags
  180.               (0x01 = NOT USED)
  181.               (0x02 = OLD_SECURED_FLAG)
  182.               (0x04 = VOLUME_FLAG)  indicates presence of succeeding
  183.                         volume
  184.               (0x08 = NOT USED)
  185.               (0x10 = PATHSYM_FLAG) indicates archive name translated
  186.                         ("\" changed to "/")
  187.               (0x20 = BACKUP_FLAG) indicates backup type archive
  188.               (0x40 = SECURED_FLAG)
  189.          1   security version (2 = current)
  190.          1   file type        (must equal 2)
  191.          1   reserved
  192.          4   date time when original archive was created
  193.          4   date time when archive was last modified
  194.          4   archive size (currently used only for secured archives)
  195.          4   security envelope file position
  196.          2   filespec position in filename
  197.          2   length in bytes of security envelope data
  198.          2   (currently not used)
  199.          ?   (currently none)
  200.  
  201.          ?   filename of archive when created (null-terminated string)
  202.          ?   archive comment  (null-terminated string)
  203.  
  204.          4   basic header CRC
  205.  
  206.          2   1st extended header size (0 if none)
  207.          ?   1st extended header (currently not used)
  208.          4   1st extended header's CRC (not present when 0 extended header size)
  209.  
  210.  
  211.       Structure of local file header (low order byte first):
  212.  
  213.       Bytes Description
  214.       ----- -------------------------------------------------------------------
  215.          2   header id (main and local file) = 0x60 0xEA
  216.          2   basic header size (from 'first_hdr_size' thru 'comment' below)
  217.          = first_hdr_size + strlen(filename) + 1 + strlen(comment) + 1
  218.          = 0 if end of archive
  219.          maximum header size is 2600
  220.  
  221.          1   first_hdr_size (size up to and including 'extr